package com.cyclingAssistant.project;

import java.util.Timer;
import java.util.TimerTask;

import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.tileprovider.util.CloudmadeUtil;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.MyLocationOverlay;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.PathOverlay;

import android.R.integer;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.FloatMath;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.cyclingAssistant.overlays.CAItemizedOverlay;
import com.cyclingAssistant.overlays.TouchableOverlay;
import com.cyclingAssistant.route.DrawRoute;
import com.cyclingAssistant.util.Geocoder;

public class CyclingAssistantActivity extends Activity {
	public static MapView mapView;
	static TouchableOverlay overlayFrom, overlayTo;
	static int zoomlevel = 15;
	MapController mapController;
	DrawRoute drawRoute, drawRoute1;
	String from = "", to = "", pref1 = "", pref2 = "";
	GeoPoint pointFrom, pointTo;
	Boolean roundTrip = false;
	DataReceiver dataReceiver;
	Boolean isTracking = false;

	public static View navi_info, search_bar;

	Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			// GeoPoint from = new GeoPoint(49.26341, -123.121845);
			// GeoPoint to = new GeoPoint(49.264139, -123.241815);
			mapController// .setCenter(from);
					.setCenter(new GeoPoint(
							(pointFrom.getLatitudeE6() + pointTo
									.getLatitudeE6()) / 2, (pointFrom
									.getLongitudeE6() + pointTo
									.getLongitudeE6()) / 2));

			// **********************
			String prefString1 = "Mainly preference 1: " + pref1;
			String prefString2 = "Combined preference for: " + pref1 + " and "
					+ pref2;

			drawRoute = new DrawRoute(Color.GREEN,
					CyclingAssistantActivity.this, true, roundTrip);
			drawRoute.setEndLat(pointTo.getLatitudeE6() / 1E6);// 49.264139
			drawRoute.setEndLng(pointTo.getLongitudeE6() / 1E6);// toAddress.getLongitude());//-123.241815
			try {
				drawRoute.showDirectionsToPredefinedLocation(
						pointFrom.getLatitudeE6() / 1E6,
						pointFrom.getLongitudeE6() / 1E6, // 49.26341,
															// -123.121845,
															// //fromAddress.getLatitude(),fromAddress.getLongitude(),
						false, "en", true);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// *******************
			drawRoute1 = new DrawRoute(Color.BLUE,
					CyclingAssistantActivity.this, false, roundTrip);
			drawRoute1.setEndLat(pointTo.getLatitudeE6() / 1E6);// 49.264139
			drawRoute1.setEndLng(pointTo.getLongitudeE6() / 1E6);// toAddress.getLongitude());//-123.241815
			try {
				drawRoute1.showDirectionsToPredefinedLocation(
						pointFrom.getLatitudeE6() / 1E6,
						pointFrom.getLongitudeE6() / 1E6, // 49.26341,
															// -123.121845,
															// //fromAddress.getLatitude(),fromAddress.getLongitude(),
						false, "en", true);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// draw information icon
			GeoPoint locPoint = drawRoute.getRandomPoint();
			Drawable route1 = CyclingAssistantActivity.this.getResources()
					.getDrawable(R.drawable.route1);

			Drawable route2 = CyclingAssistantActivity.this.getResources()
					.getDrawable(R.drawable.route2);

			OverlayItem overlayitem = new OverlayItem("Option 1", prefString1,
					locPoint);
			ItemizedIconOverlay<OverlayItem> info_overlay = new CAItemizedOverlay(
					route1, CyclingAssistantActivity.this, true, drawRoute,
					mapView);

			info_overlay.addItem(overlayitem);
			// the other information icon
			GeoPoint locPoint1 = drawRoute1.getRandomPoint();

			OverlayItem overlayitem1 = new OverlayItem("Option 2", prefString2,
					locPoint1);
			ItemizedIconOverlay<OverlayItem> info_overlay1 = new CAItemizedOverlay(
					route2, CyclingAssistantActivity.this, true, drawRoute,
					mapView);

			info_overlay1.addItem(overlayitem1);

			if (!roundTrip) {
				mapView.getOverlays().add(info_overlay);
				mapView.getOverlays().add(info_overlay1);
				mapView.getOverlays().add(drawRoute);
				mapView.getOverlays().add(drawRoute1);
			} else {
				mapView.getOverlays().add(drawRoute);
			}

			mapView.invalidate();
		};
	};

	Handler trackingHandler = new Handler() {

		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 1:
				getLocation();
				mapView.invalidate();
				Log.v("tracking request", "another");
				break;
			}
		};
	};
	PathOverlay trackPath;
	Timer timer;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// set the mapview
		mapView = (MapView) findViewById(R.id.mapview);
		CloudmadeUtil.retrieveCloudmadeKey(this);
		mapView.setTileSource(TileSourceFactory.MAPNIK);
		mapView.setBuiltInZoomControls(true);
		mapController = mapView.getController();
		mapController.setZoom(15);
		mapController.setCenter(new GeoPoint(49.263766, -123.121643));

		// set the clickable overlay

		overlayFrom = new TouchableOverlay(this, null);
		overlayTo = new TouchableOverlay(this, null);

		// 
		navi_info = findViewById(R.id.navigation_info);
		search_bar = findViewById(R.id.search_layout);

		// pinch to zoom, doesn't work now
		mapView.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				Boolean zoom = false;
				float dis = 0;
				switch (event.getAction()) {
				case MotionEvent.ACTION_POINTER_DOWN:
					zoom = true;
					dis = spacing(event);
					Log.v("distance", String.valueOf(dis));
					break;

				case MotionEvent.ACTION_MOVE:
					if (zoom == true) {
						if (spacing(event) > dis) {
							mapController.setZoom(zoomlevel++);
						} else {
							mapController.setZoom(zoomlevel--);
						}
						zoom = false;
					}
					break;
				}
				return true;

			}

			private float spacing(MotionEvent event) {
				float x = event.getX(0) - event.getX(1);
				float y = event.getY(0) - event.getY(1);
				return FloatMath.sqrt(x * x + y * y);
			}
		});

		// set the button "go"
		Button goButton = (Button) findViewById(R.id.go);
		goButton.setOnClickListener(new android.view.View.OnClickListener() {
			@Override
			public void onClick(View v) {
				mapView.getOverlays().clear();
				String location = ((EditText) findViewById(R.id.inputbox))
						.getText().toString();
				GeoPoint locPoint = Geocoder.geocoding(location);
				Drawable youRHere = CyclingAssistantActivity.this
						.getResources().getDrawable(R.drawable.you_r_here);

				OverlayItem overlayitem = new OverlayItem(
						((EditText) findViewById(R.id.inputbox)).getText()
								.toString(), Geocoder
								.getFormattedAddress(location), locPoint);
				ItemizedIconOverlay<OverlayItem> youRHere_overlay = new CAItemizedOverlay(
						youRHere, CyclingAssistantActivity.this, false, null,
						mapView);

				youRHere_overlay.addItem(overlayitem);
				mapView.getOverlays().add(youRHere_overlay);
				mapController.setCenter(locPoint);
			}
		});

		// ***************** where am I **************
		ImageButton currentLoc = (ImageButton) findViewById(R.id.button_whereami);
		currentLoc.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				final MyLocationOverlay me = new MyLocationOverlay(
						CyclingAssistantActivity.this, mapView);
				me.enableMyLocation();
				me.runOnFirstFix(new Runnable() {
					public void run() {
						mapView.getController().animateTo(me.getMyLocation());
					}
				});

				mapView.getOverlays().add(me);
			}
		});
		// ***************** tracking **************
		trackPath = new PathOverlay(Color.RED, this);
		final Button tracking = (Button) findViewById(R.id.button_tracking);
		tracking.setBackgroundColor(Color.GREEN);
		tracking.setText("start" + '\n' + "tracking");

		tracking.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// start tracking
				if (!isTracking) {
					timer = new Timer();
					trackPath.clearPath();
					mapView.getOverlays().add(trackPath);
					timer.scheduleAtFixedRate(new TimerTask() {

						@Override
						public void run() {
							trackingHandler.sendEmptyMessage(1);
						}
					}, 1, 5000);
					tracking.setText("stop" + '\n' + "tracking");
					tracking.setBackgroundColor(Color.RED);
					isTracking = true;
				}

				else {
					timer.cancel();
					Log.v("number of points",
							String.valueOf(trackPath.getNumberOfPoints()));
					Toast t = Toast
							.makeText(
									CyclingAssistantActivity.this,
									"the route is autosaved in the options menu, check it later",
									Toast.LENGTH_SHORT);
					t.show();
					mapView.invalidate();
					tracking.setText("start" + '\n' + "tracking");
					tracking.setBackgroundColor(Color.GREEN);
					isTracking = false;
				}
			}
		});

	}

	protected void getLocation() {
		final MyLocationOverlay me = new MyLocationOverlay(this, mapView);
		me.enableMyLocation();

		me.runOnFirstFix(new Runnable() {
			public void run() {
				GeoPoint point = me.getMyLocation();
				if (point != null) {
					trackPath.addPoint(point);
					Log.v("point", String.valueOf(point.getLatitudeE6()));
				} else {
					Log.v("point", "null point");
				}
			}
		});

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(Menu.NONE, Menu.FIRST + 1, 1, "clear map layers");
		menu.add(Menu.NONE, Menu.FIRST + 2, 2, "weather");
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case Menu.FIRST + 1:
			mapView.setTileSource(TileSourceFactory.MAPNIK);
			mapView.getOverlays().clear();
			break;
		case Menu.FIRST + 2:
			showDialog();
			break;

		}

		return super.onOptionsItemSelected(item);
	}

	protected void showDialog() {
		LayoutInflater inflater = LayoutInflater.from(this);
		final View textEntry = inflater.inflate(R.layout.weather, null);
		TextView temp = (TextView) textEntry.findViewById(R.id.temperature);
		temp.setText("Temperature: 8" + (char) 0x00B0 + "C");
		final AlertDialog.Builder builder = new Builder(this);
		// builder.setCancelable(false);
		builder.setTitle("Today");
		builder.setIcon(R.drawable.weather);
		builder.setView(textEntry);
		builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub

			}
		});

		builder.show();
	}

	private class DataReceiver extends BroadcastReceiver {
		// 继承自BroadcastReceiver的子类

		@Override
		public void onReceive(Context context, Intent intent) {
			// 重写onReceive方法
			from = intent.getStringExtra("from");
			to = intent.getStringExtra("to");
			roundTrip = intent.getBooleanExtra("round-trip", false);
			pref1 = intent.getStringExtra("pref1");
			pref2 = intent.getStringExtra("pref2");

			pointFrom = Geocoder.geocoding(from);
			pointTo = Geocoder.geocoding(to);
			Log.v("from:", String.valueOf(pointFrom.getLatitudeE6()) + ", "
					+ String.valueOf(pointFrom.getLongitudeE6()));
			findViewById(R.id.search_layout).setVisibility(View.GONE);
			findViewById(R.id.navigation_info).setVisibility(View.VISIBLE);

			new Thread() {
				@Override
				public void run() {
					mHandler.sendEmptyMessage(0);
				}
			}.start();

			// Geocoder coder = new Geocoder(context, Locale.CANADA);
			// new Thread() {
			// @Override
			// public void run() {
			// mHandler.sendEmptyMessage(0);
			// }
			// }.start();
			// try {
			// GeoPoint addressesFrom = coder.getFromLocationName(from,
			// 2); //, 49.102359, -123.3324, 49.310514, -122.686953);
			// if (addressesFrom.size()==0) {
			// Log.v("Size", "0!");
			// }
			// Log.v("Size", String.valueOf(addressesFrom.size()));
			// List<Address> addressesTo = coder.getFromLocationName(to, 2);
			// //,49.102359, -123.3324, 49.310514, -122.686953);
			// if (addressesFrom.size() > 0 && addressesTo.size() > 0) {
			// Log.v("from broadcast", from);
			// fromAddress = addressesFrom.get(0);
			// toAddress = addressesTo.get(0);
			// new Thread() {
			// @Override
			// public void run() {
			// mHandler.sendEmptyMessage(0);
			// }
			// }.start();
			// }
			// } catch (IOException e) {
			// e.printStackTrace();
			// Log.v("Size", e.getMessage());
			// }

		}

	}

	@Override
	protected void onStart() {
		dataReceiver = new DataReceiver();
		IntentFilter intentFilter = new IntentFilter(
				"com.cyclingAssistant.main");
		// 注册广播
		registerReceiver(dataReceiver, intentFilter);
		super.onStart();
	}

	@Override
	protected void onStop() {
		Log.v("in main", from);
		super.onStop();
	}

	@Override
	protected void onSaveInstanceState(Bundle saveInstanceState) {
		// saveInstallState.put;
		Log.v("saving state in xuanzhuan", "xuanzhuan");
		// saveInstanceState.putSerializable("overlays", (Serializable)
		// mapView.getOverlays());
		super.onSaveInstanceState(saveInstanceState);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			// moveTaskToBack(true);
			// return true;
			Intent intent = new Intent(Intent.ACTION_MAIN);
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 注意
			intent.addCategory(Intent.CATEGORY_HOME);
			this.startActivity(intent);
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}
}

//
// public class CyclingAssistantActivity extends MapActivity {
// private MapView mapView;
// private Road mRoad;
// public String from = "", to = "", pref1 = "", pref2 = "";
// public Boolean roundTrip = false;
// private DataReceiver dataReceiver;
//
// @Override
// public void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
//
// mapView = (MapView) findViewById(R.id.mapview);
// mapView.setBuiltInZoomControls(true);
//
// new Thread() {
// @Override
// public void run() {
// double fromLat = 49.264139, fromLon = -123.241815, toLat = 49.26341, toLon =
// -123.121845;
// String url = RoadProvider
// .getUrl(fromLat, fromLon, toLat, toLon);
// // String url = new
// // String("http://www.cyclevancouver.ubc.ca/KML/designated.kml");
// Log.v("url", url);
// InputStream is = getConnection(url);
// mRoad = RoadProvider.getRoute(is);
// mHandler.sendEmptyMessage(0);
// }
// }.start();
// }
//
// Handler mHandler = new Handler() {
// public void handleMessage(android.os.Message msg) {
// // TextView textView = (TextView) findViewById(R.id.description);
// // textView.setText(mRoad.mName + " " + mRoad.mDescription);
// MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
// List<Overlay> listOfOverlays = mapView.getOverlays();
// listOfOverlays.clear();
// listOfOverlays.add(mapOverlay);
// mapView.invalidate();
// };
// };
//
// private InputStream getConnection(String url) {
// InputStream is = null;
// try {
// URLConnection conn = new URL(url).openConnection();
// is = conn.getInputStream();
// } catch (MalformedURLException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }
// return is;
// }
//
// @Override
// protected boolean isRouteDisplayed() {
// return false;
// }
//
// private class DataReceiver extends BroadcastReceiver {//
// 继承自BroadcastReceiver的子类
//
// @Override
// public void onReceive(Context context, Intent intent) {// 重写onReceive方法
// from = intent.getStringExtra("from");
// to = intent.getStringExtra("to");
// roundTrip = intent.getBooleanExtra("round-trip", false);
// pref1 = intent.getStringExtra("pref1");
// pref2 = intent.getStringExtra("pref2");
// Log.v("from broadcast", from);
// }
// }
//
// @Override
// protected void onStart() {
// dataReceiver = new DataReceiver();
// IntentFilter intentFilter = new IntentFilter(
// "com.cyclingAssistant.main");
// // 注册广播
// registerReceiver(dataReceiver, intentFilter);
// super.onStart();
// }
//
// @Override
// protected void onStop() {
// Log.v("in main", from);
// super.onStop();
// }
// }
//
// class MapOverlay extends com.google.android.maps.Overlay {
// Road mRoad;
// ArrayList<GeoPoint> mPoints;
//
// public MapOverlay(Road road, MapView mv) {
// mRoad = road;
// if (road.mRoute.length > 0) {
// mPoints = new ArrayList<GeoPoint>();
// for (int i = 0; i < road.mRoute.length; i++) {
// mPoints.add(new GeoPoint((int) (road.mRoute[i][1] * 1000000),
// (int) (road.mRoute[i][0] * 1000000)));
// }
// int centerLat = (mPoints.get(0).getLatitudeE6() + (mPoints.get(
// mPoints.size() - 1).getLatitudeE6() - mPoints.get(0)
// .getLatitudeE6()) / 2);
// int centerLong = (mPoints.get(0).getLongitudeE6() + (mPoints.get(
// mPoints.size() - 1).getLongitudeE6() - mPoints.get(0)
// .getLongitudeE6()) / 2);
// GeoPoint center = new GeoPoint(centerLat, centerLong);
//
// MapController mapController = mv.getController();
// mapController.animateTo(center);
// mapController.setZoom(13);
// }
// }
//
// @Override
// public boolean draw(Canvas canvas, MapView mv, boolean shadow, long when) {
// super.draw(canvas, mv, shadow);
// drawPath(mv, canvas);
// return true;
// }
//
// public void drawPath(MapView mv, Canvas canvas) {
// int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
// Paint paint = new Paint();
// paint.setColor(Color.GREEN);
// paint.setStyle(Paint.Style.STROKE);
// paint.setStrokeWidth(3);
// for (int i = 0; i < mPoints.size(); i++) {
// Point point = new Point();
// mv.getProjection().toPixels(mPoints.get(i), point);
// x2 = point.x;
// y2 = point.y;
// if (i > 0) {
// canvas.drawLine(x1, y1, x2, y2, paint);
// }
// x1 = x2;
// y1 = y2;
// }
// }
// }